작성 일자 : 2026-01-06

기획

어쩌다가 일을 맡게 되었다. 무수히 많은 사이트를 들어가서 화면 캡쳐를 하고, 이 URL에 이 화면이 나온다는 것을 PPT로 만들어야 한다.

꾸미는 것은 둘째치고 n00개 되는 양을 매번 캡쳐, PPT로 이동 하는 것은 쉽지 않은 일이다.

그래서 컴팩트하게 자동화하여 진행하고자 한다.

목표는 크게 3가지 이다.

  • url은 csv 양식으로 입력 받음. index와 함께 편리한 입력
  • 캡쳐된 이미지는 index이름으로 저장.
  • PPT에 화면과 함께 저장되며 상단에 url 텍스트 박스로 입력.

INPUT

  • 사용자가 캡쳐해야하는 무수히 많은 URL CSV 파일 OUTPUT
  • 지정된 경로에 캡쳐본 저장
  • 캡쳐본을 통해 PPT로 제작
  • (들어가지 못하는 사이트일 경우 누락된 URL 따로 보관)

설계

필요 기술

Playwrite

  • Selenium과 굉장히 비슷한 친구.
  • Chromium / Firefox / WebKit을 제어하는 브라우저 자동화 도구, JS 렌더링 페이지 캡쳐에 안정적
  • Headless 실행, Full-page 스크린 샷, 네트워크 대기 등 웹 자동화에 필요한 기능을 기본 제공함

python-pptx

  • Python에서 PPTX 파일을 생성, 편집하기 위한 라이브러리
  • 슬라이드 추가, 텍스트 박스, 이미지 삽입, 레이아웃 제어 등을 코드로 제어 가능함

구현 순서

  1. CSV 양식 만들기
    1. 테스트 데이터셋 만들기 (5개 정도)
  2. playwright로 스크린샷 저장되는 것 구현
    1. 캡쳐본 이름을 index로 저장하기 구현
  3. python-pptx 도입해서 PPT화 하기

구현 완료

uv add playwright pandas python-pptx pillow
uv run playwright install chromium

Template idx에 인덱스를 입력하고 url을 우측에 입력하게 둔다.

Result 실행 날짜 기준으로 폴더가 생긴다. 현재는 example로 5개의 url을 진행하였다.

양식에 맞게 넣은 url 들 캡쳐본이 index이름으로 저장되고 가장 마지막에 result.pptx가 생성된다.

이렇게 간단하게 PPT 빈 화면에 캡쳐본과 url 만 두었다. 세부적인건 추후 수정 예정!

만약 실패한다면 빈 화면에 실패 URL이 입력되며 실패한 URL만 따로 모아 CSV가 생성된다.


시행착오

  • 페이지 전체 로드 안됨.

    • time out 기점을 1000으로 생성하니 특정 웹페이지가 제대로 로드 되기 전에 캡쳐하여 어그러지는 경우가 있었다.
    • 그래서 time out 기점을 3000으로 늘렸다.
  • n00개 진행할 시 느린 속도

    • 기본적인 반복문으로 진행하니 timeout 페이지가 걸릴 경우 너무 오랜 시간이 소요되었다.
    • 그래서 비동기 방식 병렬 처리를 진행하였으며 실패한 케이스는 별도로 모아서 관리하기로 하였다.
  • PPT 이미지 삽입

    • 세로가 긴 이미지라면 PPT 양식에 의해 화면을 억지로 늘려서 넣었었다.
    • 가독성이 좋지 않아 세로를 중점으로 이미지를 맞추고 추후에 가로 이미지를 관리하기로 수정하였다.

한계점과 개선점

  • 애플, 네이버와 같은 대규모 웹페이지 전체 로드 안됨.

    • 일부 페이지는 렌더링 방식때문에 그럴 수도 있다고함.
    • 사용자의 스크롤에 따라 움직이는 페이지여서 그런 경우 있음.
    • 하지만 내가 필요한 페이지는 대부분 정적인 페이지일 것이기 때문에 괜찮을 것으로 예상됨
  • 전체 페이지를 캡쳐해야하는가? 에 대한 의문이 생김

    • 만약 전체 페이지가 아닌 보이는 페이지 캡쳐만 원한다면 viewport 캡쳐를 진행하면 될 것 같음.

작성 일자 : 2026-01-07

수정사항

  1. PPT를 빈 페이지가 아닌 기존에 사용하던 템플릿을 재응용 예정 빈 페이지에 삽입 X 기존 주어진 양식에 수정

  2. idx, url 뿐만이 아닌 result와 measured_time 을 삽입. PPT에 이미지 뿐 아니라 ‘표’를 제어하는 기능 필요함.

  3. 모바일 기기를 기준으로 촬영한 사진 필요함 기존 웹에서 촬영한 스크린샷이 아닌 모바일 UI 기준으로 캡쳐해야함.

  4. 웹페이지 전체 캡쳐가 아닌 첫 화면 캡쳐 전체 캡쳐도 혹시 몰라 구현해야하며 모바일 첫 입장 화면 캡쳐

기존 방식 수정된 방식

웹페이지 접속 및 캡쳐
  • 현재 코드 실행 시간을 기점으로 result에 폴더 생성
  • source/template.csv에 넣은 값들을 기점으로 playwright을 순환하며 화면 캡쳐
  • 캡쳐한 이미지는 idx를 기준으로 result 폴더 내에 스크린샷 저장

(기존 방식) PPT 생성
  • 비어있는 PPT를 생성하여 슬라이드 번호에 맞게 이미지 삽입
  • 이미지 상단에 텍스트 박스 생성하여 URL 입력 (CSV load)
(수정된 방식) PPT 로드
  • source/template_ppt.pptx에 ppt 파일 로드
  • 첫 페이지는 template 원본으로 냅두고 페이지 복사
  • 각 template의 위치에 맞는 값 삽입
  • 비어있는 도형에 이미지 삽입

시행착오

  • 없는 URL에 대한 PPT 페이지 생성 에러

    • 처음 1 ~ 10의 URL을 가지고 develop을 진행함.
    • 1,3,5,6 의 URL을 제외한 나머지 URL은 접속이 안되는 상황
    • 2,4,7,8,9,10 의 페이지가 빈 template양식으로 나와야 하는데 1번과 3번에 2개의 빈 템플릿 발견
    • 숫자 10이 sort 과정에서 1과 2 사이에 들어있는 것을 발견함.
    • idx를 int값으로 치환하여 재 sort 진행 과정 삽입하여 해결함
  • 병합된 표의 좌표값 확인

    • 병합된 표의 좌표를 찾는 것은 어려웠음.
    • 처음에는 0,0 좌표부터 값을 하나씩 넣으면서 run을 진행함.
    • 표의 사이즈를 벗어나도 정상 작동되는 것을 보고 직접 수기 입력 식 디버깅은 한계가 있다고 판단함.
    • GPT의 도움으로 표 전체의 내용물을 확인하는 디버깅코드 작성
def debug_table_structure(slide):
 
    table = 슬라이드 내 테이블 셀렉(slide)
 
	# 테이블 제대로 잡았는지 검토
    if table is None:
        print("table not found")
        return
 
    rows = len(table.rows)
    cols = len(table.columns)
 
    print(f"TABLE SIZE: rows={rows}, cols={cols}")
 
    for r in range(rows):
        for c in range(cols):
            text = table.cell(r, c).text.replace("\n", " ")
            print(f"cell({r},{c}) = '{text}'")
  • 삽입하는 글자의 사이즈 문제

    • 템플릿 자체의 서식 속성을 유지 받지 못하는점 발견
    • 여러 방식을 고민하다가 일단 해결이 목표였기 때문에 삽입 과정에서 폰트 사이즈, 속성 변경
    • 삽입 하는 과정 속에서 각 위치별 텍스트 사이즈, 볼드 조절함
  • 빠른 개발 디벨롭 방식

    • 정상, 비정상이 섞여있는 URL로 테스트하는 것에 몇초 차이이지만 빠른 결과 확인이 힘들었음
    • 다음에 진행한다면?
      • 정상 URL이 들어있는 csv 1개 지금 하고 있는 구현이 가능한지?
      • 정상 URL 1개, 비정상 URL 1개 들어있는 csv 1개 비정상인 URL은 어떻게 처리하는지?
      • 정상 URL 1,3,7번, 비정상 URL 나머지 들어있는 csv 1개 정상, 비정상이 섞여있는 경우 빈 페이지를 어떤 식으로 생성하는지?
  • GPT 로직 구성의 한계

    • PPT 생성에 있어서 잘 모르는 분야이기 때문에 처음엔 GPT의 코드 진행을 맡기고 믿음
    • 하지만 진행하는 것에 있어서 비효율적이고 디버깅의 불편한 점을 여럿 발견
    • 잘 모르는 분야여도 혼자 진행 로직에 대해 고민하고 GPT에게 시키는 것이 더 정확할 것이라는 깨달음을 얻음
    • 기획을 꼼꼼히 하고 프로젝트를 진행하자
공부한 내용 정리

01_비동기 문법 02_데이터 순회